package com.sgu6.netty.handler;

import android.util.Log;

import com.sgu6.middleware.enums.MachineStatusEnum;
import com.sgu6.middleware.event.MachineStatusEvent;
import com.sgu6.middleware.log.Logger;
import com.sgu6.netty.NettyClient;
import com.sgu6.netty.common.Constant;
import com.sgu6.netty.container.ChannelContainer;
import com.sgu6.netty.protobuffer.NettyMessageProto;
import com.sgu6.netty.utils.NettyHelper;
import com.sgu6.netty.utils.RandomUtils;
import com.sgu6.netty.utils.SignatureUtils;

import org.greenrobot.eventbus.EventBus;

import java.util.Date;
import java.util.Timer;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;


public class LoginHandler extends ChannelHandlerAdapter {

    protected final String TAG = LoginHandler.class.getSimpleName();

    private String machineNo;
    private String machineVersion;
    private String host;
    private int port;
    private HeartbeatTask task;
    private Timer timer = new Timer();

    public LoginHandler(String machineNo, String machineVersion, String host, int port) {
        this.machineNo = machineNo;
        this.machineVersion = machineVersion;
        this.host = host;
        this.port = port;
        this.task = new HeartbeatTask(machineNo, machineVersion);
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ChannelContainer.CHANNEL = ctx;
        //生成认证sign
        String nonceStr = RandomUtils.getRandomString(16);
        long timestamp = new Date().getTime();
        String signature = SignatureUtils.generateSignature(machineNo, String.valueOf(timestamp), nonceStr);
        NettyHelper.postMsgWithLoginReq(machineNo, nonceStr, timestamp, signature);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyMessageProto.NettyMessage packet = (NettyMessageProto.NettyMessage) msg;
        if (packet.getHeader() != null && packet.getHeader().getType() == NettyMessageProto.Header.Type.LOGIN_RESP) {
            NettyMessageProto.Msg returnMsg = packet.getBody().unpack(NettyMessageProto.Msg.class);
            if (returnMsg.getResult()) {
                //登录成功
                EventBus.getDefault().post(new MachineStatusEvent(MachineStatusEnum.待机.code()));
                Logger.v(TAG, "机器登录成功", true);
                timer.schedule(task, 1000, Constant.SOCKET_HEART_BEAT_TIME * 1000);
            }
        } else {
            ctx.fireChannelRead(msg);
        }

    }

    @Override
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
        EventBus.getDefault().post(new MachineStatusEvent(MachineStatusEnum.离线.code()));
        ctx.close(promise);

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if (task != null) {
            task.cancel();
            task = null;
        }
        Log.i(TAG, "channelInactive: ========connect");
        EventBus.getDefault().post(new MachineStatusEvent(MachineStatusEnum.离线.code()));
        NettyClient.INSTANCE.connect(machineNo, machineVersion, host, port);
    }

    @Override
    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        ctx.disconnect(promise);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        EventBus.getDefault().post(new MachineStatusEvent(MachineStatusEnum.离线.code()));
        Channel channel = ctx.channel();
        cause.printStackTrace();
        if (channel.isActive()) {
            Logger.v(TAG, "exceptionCaught: client" + channel.remoteAddress() + "异常", true);
        }
    }
}
